package com.amway.qy.util.common;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.amway.qy.message.resp.RespImageMessage;
import com.amway.qy.message.resp.RespNewsMessage;
import com.amway.qy.message.resp.RespTextMessage;
import com.amway.qy.message.resp.RespVideoMessage;
import com.amway.qy.message.resp.RespVoiceMessage;
import com.amway.qy.message.resp.section.RespArticleSection;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

/*
 * 主要为企业号的相关转换提供便利，包括流转为Map,对象转为XML
 * 
 * 注意事项：
 *    由于该转换是基于 xstream 完成的，但该工具包对于动态匿名类或者是动态匿名集合的支持不足。所以，千万别试图用 匿名类来完成转换。除非，用static标注。
 * 
 */

public class XmlUtils {
	/*
	 * 自定一个XML对象序列器，对所有写出的字段 都附加，非转义要求。
	 */
	private static XStream xstream = new XStream(new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				boolean cdata = true;

				@Override
				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write("<![CDATA[");
						writer.write(text);
						writer.write("]]>");
					} else {
						writer.write(text);
					}
				}

			};
		}
	});
	
	
	
	public static String convertTextMessageToXml(RespTextMessage text){
		xstream.alias("xml", text.getClass());
		return xstream.toXML(text);
	}
	
	public static String convertImageMessageToXml(RespImageMessage image){
		xstream.alias("xml", image.getClass());		
		return xstream.toXML(image);
	}
	
	public static String convertVideoMessageToXml(RespVideoMessage video){
		xstream.alias("xml", video.getClass());		
		return xstream.toXML(video);
	}
	
	public static String convertVoiceMessageToXml(RespVoiceMessage voice){
		xstream.alias("xml", voice.getClass());		
		return xstream.toXML(voice);
	}
	
	public static String convertNewsMessageToXml(RespNewsMessage news){
		xstream.alias("xml", RespNewsMessage.class);
		xstream.alias("item",RespArticleSection.class);
		return xstream.toXML(news);
	}

	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();
		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}
	
	/**
	 * 将微信回调传入的请求，转为Map。
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> parseXml(ByteArrayInputStream inputStream) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		Element root = document.getRootElement();
		List<Element> elementList = root.elements();
		for (Element e : elementList)
			map.put(e.getName(), e.getText());
		return map;
	}
	
	public static Map<String,String> parseXml(String xmlContent) throws Exception{
		ByteArrayInputStream bis = new ByteArrayInputStream(xmlContent.getBytes());
		return parseXml(bis);
	}
	
	public static Map<String,String> parseXml(InputStream is) throws Exception{
		return parseXml(convertStreamToString(is));
	}
}
